package service

import (
	"errors"
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/repository"
	"log"
	"strings"
	"sync"

	"gorm.io/gorm"
)

// SensitiveWordService 敏感词服务接口
type SensitiveWordService interface {
	// 敏感词管理
	CreateSensitiveWord(createdBy uint, req *model.CreateSensitiveWordReq) (*model.SensitiveWord, error)
	GetSensitiveWord(id uint) (*model.SensitiveWord, error)
	GetSensitiveWordList(req *model.SensitiveWordListReq) (*model.SensitiveWordListResp, error)
	UpdateSensitiveWord(id uint, req *model.UpdateSensitiveWordReq) error
	DeleteSensitiveWord(id uint) error
	
	// 敏感词过滤
	FilterText(text string) *model.FilterResult
	ReloadSensitiveWords() error
}

// sensitiveWordService 敏感词服务实现
type sensitiveWordService struct {
	repo         *repository.SensitiveWordRepository
	wordsCache   []model.SensitiveWord // 敏感词缓存
	mu           sync.RWMutex          // 读写锁
}

// NewSensitiveWordService 创建敏感词服务
func NewSensitiveWordService(repo *repository.SensitiveWordRepository) SensitiveWordService {
	service := &sensitiveWordService{
		repo:       repo,
		wordsCache: []model.SensitiveWord{},
	}
	
	// 初始化加载敏感词
	if err := service.ReloadSensitiveWords(); err != nil {
		log.Printf("[敏感词] 初始化加载敏感词失败: %v", err)
	} else {
		log.Printf("[敏感词] 已加载 %d 个敏感词", len(service.wordsCache))
	}
	
	return service
}

// CreateSensitiveWord 创建敏感词
func (s *sensitiveWordService) CreateSensitiveWord(createdBy uint, req *model.CreateSensitiveWordReq) (*model.SensitiveWord, error) {
	// 检查是否已存在
	exists, err := s.repo.CheckExists(req.Word)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, errors.New("该敏感词已存在")
	}

	word := &model.SensitiveWord{
		Word:      strings.TrimSpace(req.Word),
		Category:  req.Category,
		Level:     req.Level,
		Action:    req.Action,
		IsEnabled: true,
		CreatedBy: createdBy,
	}

	if err := s.repo.Create(word); err != nil {
		return nil, err
	}

	// 重新加载敏感词缓存
	s.ReloadSensitiveWords()

	log.Printf("[敏感词] 创建敏感词: %s, 分类: %s, 级别: %s", word.Word, word.Category, word.Level)
	return word, nil
}

// GetSensitiveWord 获取敏感词详情
func (s *sensitiveWordService) GetSensitiveWord(id uint) (*model.SensitiveWord, error) {
	word, err := s.repo.GetByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("敏感词不存在")
		}
		return nil, err
	}
	return word, nil
}

// GetSensitiveWordList 获取敏感词列表
func (s *sensitiveWordService) GetSensitiveWordList(req *model.SensitiveWordListReq) (*model.SensitiveWordListResp, error) {
	// 参数验证
	if req.Page < 1 {
		req.Page = 1
	}
	if req.PageSize < 1 || req.PageSize > 100 {
		req.PageSize = 20
	}

	words, total, err := s.repo.GetList(req)
	if err != nil {
		return nil, err
	}

	return &model.SensitiveWordListResp{
		List:     words,
		Total:    total,
		Page:     req.Page,
		PageSize: req.PageSize,
	}, nil
}

// UpdateSensitiveWord 更新敏感词
func (s *sensitiveWordService) UpdateSensitiveWord(id uint, req *model.UpdateSensitiveWordReq) error {
	// 检查敏感词是否存在
	_, err := s.repo.GetByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("敏感词不存在")
		}
		return err
	}

	// 构建更新字段
	updates := make(map[string]interface{})
	if req.Category != "" {
		updates["category"] = req.Category
	}
	if req.Level != "" {
		updates["level"] = req.Level
	}
	if req.Action != "" {
		updates["action"] = req.Action
	}
	if req.IsEnabled != nil {
		updates["is_enabled"] = *req.IsEnabled
	}

	if len(updates) == 0 {
		return errors.New("没有需要更新的字段")
	}

	if err := s.repo.Update(id, updates); err != nil {
		return err
	}

	// 重新加载敏感词缓存
	s.ReloadSensitiveWords()

	log.Printf("[敏感词] 更新敏感词 ID: %d", id)
	return nil
}

// DeleteSensitiveWord 删除敏感词
func (s *sensitiveWordService) DeleteSensitiveWord(id uint) error {
	// 检查敏感词是否存在
	_, err := s.repo.GetByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("敏感词不存在")
		}
		return err
	}

	if err := s.repo.Delete(id); err != nil {
		return err
	}

	// 重新加载敏感词缓存
	s.ReloadSensitiveWords()

	log.Printf("[敏感词] 删除敏感词 ID: %d", id)
	return nil
}

// FilterText 过滤文本中的敏感词
func (s *sensitiveWordService) FilterText(text string) *model.FilterResult {
	s.mu.RLock()
	defer s.mu.RUnlock()

	if text == "" {
		return &model.FilterResult{
			Passed:       true,
			FilteredText: text,
			HitWords:     []string{},
		}
	}

	result := &model.FilterResult{
		Passed:          true,
		FilteredText:    text,
		HitWords:        []string{},
		HighestLevel:    "",
		SuggestedAction: model.SensitiveWordActionReplace,
	}

	// 转换为小写进行匹配（不区分大小写）
	lowerText := strings.ToLower(text)
	filteredText := text

	// 遍历所有启用的敏感词
	for _, word := range s.wordsCache {
		if !word.IsEnabled {
			continue
		}

		lowerWord := strings.ToLower(word.Word)
		if strings.Contains(lowerText, lowerWord) {
			result.HitWords = append(result.HitWords, word.Word)

			// 更新最高敏感级别
			if result.HighestLevel == "" || s.compareLevels(word.Level, result.HighestLevel) > 0 {
				result.HighestLevel = word.Level
				result.SuggestedAction = word.Action
			}

			// 根据动作处理
			switch word.Action {
			case model.SensitiveWordActionReplace:
				// 替换为 ***
				replacement := strings.Repeat("*", len(word.Word))
				filteredText = s.replaceIgnoreCase(filteredText, word.Word, replacement)
				
			case model.SensitiveWordActionReject:
				// 拒绝发送
				result.Passed = false
				
			case model.SensitiveWordActionWarn:
				// 仅警告，不阻止
				// 可以在前端展示警告信息
			}
		}
	}

	result.FilteredText = filteredText

	if len(result.HitWords) > 0 {
		log.Printf("[敏感词] 检测到敏感词: %v, 最高级别: %s, 动作: %s", 
			result.HitWords, result.HighestLevel, result.SuggestedAction)
	}

	return result
}

// ReloadSensitiveWords 重新加载敏感词缓存
func (s *sensitiveWordService) ReloadSensitiveWords() error {
	words, err := s.repo.GetAllEnabled()
	if err != nil {
		return err
	}

	s.mu.Lock()
	s.wordsCache = words
	s.mu.Unlock()

	log.Printf("[敏感词] 重新加载敏感词缓存，共 %d 个", len(words))
	return nil
}

// compareLevels 比较敏感级别大小（HIGH > MEDIUM > LOW）
func (s *sensitiveWordService) compareLevels(level1, level2 string) int {
	levelMap := map[string]int{
		model.SensitiveWordLevelLow:    1,
		model.SensitiveWordLevelMedium: 2,
		model.SensitiveWordLevelHigh:   3,
	}

	val1 := levelMap[level1]
	val2 := levelMap[level2]

	if val1 > val2 {
		return 1
	} else if val1 < val2 {
		return -1
	}
	return 0
}

// replaceIgnoreCase 不区分大小写替换字符串
func (s *sensitiveWordService) replaceIgnoreCase(text, old, new string) string {
	lowerOld := strings.ToLower(old)
	
	result := text
	index := 0
	
	for {
		pos := strings.Index(strings.ToLower(result[index:]), lowerOld)
		if pos == -1 {
			break
		}
		
		actualPos := index + pos
		result = result[:actualPos] + new + result[actualPos+len(old):]
		index = actualPos + len(new)
	}
	
	return result
}

